package cuongnh.project.japanesediary.vocabulary.ui.editor.kanji.page.category;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.beans.BeansObservables;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
import org.eclipse.jface.databinding.viewers.ObservableSetContentProvider;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.ui.forms.DetailsPart;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.MasterDetailsBlock;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.editor.FormPage;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;

import cuongnh.project.japanesediary.vocabulary.application.Activator;
import cuongnh.project.japanesediary.vocabulary.common.CommonServices;
import cuongnh.project.japanesediary.vocabulary.model.Category;
import cuongnh.project.japanesediary.vocabulary.model.Kanji;
import cuongnh.project.japanesediary.vocabulary.ui.dialog.AddRelatedCategoryDialog;
import cuongnh.project.japanesediary.vocabulary.ui.editor.kanji.KanjiEditorInput;

public class KanjiCategoryBlock extends MasterDetailsBlock {
	private DataBindingContext m_bindingContext;

	private FormPage page;
	private Kanji kanji;
	private CommonServices commonServices;
	private TableViewer treeViewer;

	/**
	 * @wbp.parser.entryPoint
	 */
	public KanjiCategoryBlock(FormPage page,
			CommonServices commonServices) {
		this.page = page;
		this.commonServices = commonServices;
		initData();
	}

	private void initData() {
		kanji = commonServices.getKanjiDao().getKanjiWithCategories(
				((KanjiEditorInput) page.getEditor().getEditorInput()).getId());
	}

	private void refresh() {
		m_bindingContext.updateModels();
		treeViewer.refresh();
	}

	protected void createMasterPart(final IManagedForm managedForm,
			Composite parent) {
		FormToolkit toolkit = managedForm.getToolkit();
		Section section = toolkit.createSection(parent, Section.DESCRIPTION
				| Section.TITLE_BAR);
		section.setText("Category list"); //$NON-NLS-1$
		section.setDescription("List of all categories this Kanji belong to"); //$NON-NLS-1$
		section.marginWidth = 10;
		section.marginHeight = 5;
		createCategoryListToolBar(section);
		Composite client = toolkit.createComposite(section, SWT.WRAP);
		GridLayout layout = new GridLayout();
		layout.marginWidth = 2;
		layout.marginHeight = 2;
		client.setLayout(layout);
		toolkit.paintBordersFor(client);

		treeViewer = new TableViewer(client, SWT.BORDER);
		Table tree = treeViewer.getTable();
		GridData gd_tree = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
		gd_tree.widthHint = 150;
		tree.setLayoutData(gd_tree);
		toolkit.paintBordersFor(tree);
		section.setClient(client);
		final SectionPart spart = new SectionPart(section);
		managedForm.addPart(spart);
		treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				managedForm.fireSelectionChanged(spart, event.getSelection());
			}
		});
		m_bindingContext = initDataBindings();
	}
	
	private void createCategoryListToolBar(final Section section) {
		ToolBar toolbar = new ToolBar(section, SWT.FLAT);
		section.setTextClient(toolbar);

		ToolItem addItem = new ToolItem(toolbar, SWT.PUSH);
		addItem.setImage(Activator.getImageDescriptor("/icons/add.gif")
				.createImage());
		addItem.setToolTipText("Add a Category for this vocabulary");

		addItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				AddRelatedCategoryDialog addRelatedCategoryDialog = new AddRelatedCategoryDialog(
						section.getShell(), commonServices);
				if (addRelatedCategoryDialog.open() == Window.OK) {
					Category selectedCategory = addRelatedCategoryDialog.getCategory();
					kanji.getKanjiCategories().add(selectedCategory);
					commonServices.getKanjiDao().merge(kanji);
					refresh();
					treeViewer.setSelection(new StructuredSelection(
							selectedCategory));
				}
			}
		});

		ToolItem removeItem = new ToolItem(toolbar, SWT.PUSH);
		removeItem.setImage(Activator.getImageDescriptor("/icons/delete.gif")
				.createImage());
		removeItem
				.setToolTipText("Remove selected Category that this grammar belong to");

		removeItem.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				IStructuredSelection selection = (IStructuredSelection) treeViewer
						.getSelection();
				Category selectedCategory = (Category) selection
						.getFirstElement();
				boolean confirm = MessageDialog.openConfirm(section.getShell(),
						"Confirm Delete",
						"Are you sure you want to delete this Category?");
				if (confirm) {
					// remove selected Category from Grammar
					kanji.getKanjiCategories().remove(selectedCategory);
					commonServices.getKanjiDao().merge(kanji);

					// refresh treeviewer
					m_bindingContext.updateModels();
					refresh();
				}
			}
		});
	}

	protected void createToolBarActions(IManagedForm managedForm) {
		final ScrolledForm form = managedForm.getForm();
		form.setOrientation(SWT.HORIZONTAL);
		Action haction = new Action("hor", Action.AS_RADIO_BUTTON) { //$NON-NLS-1$
			public void run() {
				sashForm.setOrientation(SWT.HORIZONTAL);
				form.reflow(true);
			}
		};
		haction.setChecked(true);
		haction.setToolTipText("Horizontal"); //$NON-NLS-1$
		haction.setImageDescriptor(Activator.getImageDescriptor("/icons/horizontal.gif"));

		Action vaction = new Action("ver", Action.AS_RADIO_BUTTON) { //$NON-NLS-1$
			public void run() {
				sashForm.setOrientation(SWT.VERTICAL);
				form.reflow(true);
			}
		};
		vaction.setChecked(false);
		vaction.setToolTipText("Vertical"); //$NON-NLS-1$
		vaction.setImageDescriptor(Activator.getImageDescriptor("/icons/vertical.gif"));		
		form.getToolBarManager().add(haction);
		form.getToolBarManager().add(vaction);
	}

	protected void registerPages(DetailsPart detailsPart) {
		detailsPart.registerPage(Category.class,
				new KanjiCategoryDetailsPage(commonServices));
	}

	protected DataBindingContext initDataBindings() {
		DataBindingContext bindingContext = new DataBindingContext();
		//
		ObservableSetContentProvider setContentProvider = new ObservableSetContentProvider();
		IObservableMap observeMap = BeansObservables.observeMap(
				setContentProvider.getKnownElements(), Category.class,
				"categoryName");
		treeViewer.setLabelProvider(new ObservableMapLabelProvider(observeMap));
		treeViewer.setContentProvider(setContentProvider);
		//
		IObservableSet categoriesVocabularyObserveSet = BeanProperties.set(
				"kanjiCategories").observe(kanji);
		treeViewer.setInput(categoriesVocabularyObserveSet);
		//
		return bindingContext;
	}
	
	@Override
	public void createContent(IManagedForm managedForm) {
		super.createContent(managedForm);
		sashForm.setWeights(new int[] { 1, 3 });
	}

}
